package com.miyake.dsp.filter.ui;

import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.miyake.dsp.ProcessorFactory;
import com.miyake.dsp.ScilabFactory;
import com.miyake.dsp.filter.Filter;
import com.miyake.dsp.filter.FilterSetting;
import com.miyake.dsp.filter.FilterSetting.FilterAlgo;
import com.miyake.dsp.filter.FilterSetting.FilterType;
import com.miyake.dsp.ui.DspComboBox;
import com.miyake.dsp.ui.DspTextField;
import com.miyake.dsp.ui.DspWidget;
import com.miyake.dsp.ui.DspWidget.DspWidgetHandler;

public class FilterSettingPanel extends DspWidget {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6273817334338437752L;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		double samplingFrequency = 100;
		int taps = 10;
		double cutoff = 30;
		
		ProcessorFactory factory = new ScilabFactory(samplingFrequency);
		FilterSetting setting = new FilterSetting(FilterAlgo.Butterworth, FilterType.Lowpass, taps, cutoff);
		JFrame frame = new JFrame();
		frame.getContentPane().add(new FilterSettingPanel(setting));
		frame.setVisible(true);
		frame.pack();
	}

	enum CutoffType {
		Low, High
	}
	
	Filter filter = null;
	protected FilterSetting setting;
	public FilterSettingPanel(FilterSetting setting) {
		super();
		this.setting = setting;
		initialize();
	}

	DspTextField cutoffLowWidget = null;
	DspTextField cutoffHighWidget = null;
	private void initialize() {
//		this.removeAll();
		createFilterAlgo(setting.getFilterAlgo());
		createFilterType(setting.getFilterType());
//		createSamplingFrequency(setting.getFrequency());
		createTap(setting.getOrder());
		cutoffLowWidget = createCutoff(CutoffType.Low, setting.getCutoff1());
		cutoffLowWidget.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setCutoff1(Double.valueOf(value));
				fireChange(value);
			}
		});
		cutoffHighWidget = createCutoff(CutoffType.High, setting.getCutoff2());	
		cutoffHighWidget.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setCutoff2(Double.valueOf(value));
				fireChange(value);
			}
		});
		
		createDelta(setting.getDelta1(), setting.getDelta2());
	}
	
	private void createDelta(double delta1, double delta2) {
		JPanel p = new JPanel();
		p.setLayout(new FlowLayout());
		DspTextField text1 = new DspTextField("Delta1");
		text1.setValue(String.valueOf(delta1));
		p.add(text1);
		text1.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setDelta1(Double.valueOf(value));
				fireChange(value);
			}
		});
		
		DspTextField text2 = new DspTextField("Delta2");
		text2.setValue(String.valueOf(delta1));
		p.add(text2);
		text2.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setDelta2(Double.valueOf(value));
				fireChange(value);
			}
		});
		this.add(p);
	}

	private final String butterworth = "Butterworth";
	private final String chebyshev1 = "Chebyshev1";
	private final String chebyshev2 = "Chebyshev2";
	private final String elliptic = "Elliptic";
	private final String fir = "Fir";
	private void createFilterAlgo(FilterAlgo type) {
		List<String> list = new ArrayList<String>();
		list.add(butterworth);
		list.add(chebyshev1);
		list.add(chebyshev2);
		list.add(elliptic);
		list.add(fir);
		DspComboBox combo = new DspComboBox("Algo", list);
		if (type.equals(FilterType.Lowpass)) {
			combo.setSelected(lowpass);
		}
		else if (type.equals(FilterType.Highpass)) {
			combo.setSelected(highpass);
		}
		else if (type.equals(FilterType.Bandpass)) {
			combo.setSelected(bandpass);
		}
		else if (type.equals(FilterType.Stopband)) {
			combo.setSelected(stopband);
		}
		
		this.add(combo);
		
		combo.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				updateAlgoState(value);
				fireChange(value);
			}
		});
	}

	private void createTap(int taps) {
		DspTextField text = new DspTextField("Order");
		text.setValue(String.valueOf(taps));
		this.add(text);
		text.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setOrder(Integer.valueOf(value));
				fireChange(value);
			}
		});	
	}

	private void createSamplingFrequency(double freq) {
		DspTextField text = new DspTextField("Sampling Frequency");
		text.setValue(String.valueOf(freq));
		this.add(text);
		text.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setFrequency(Double.valueOf(value));
				fireChange(value);
			}
		});
	}
	
	private final String lowpass = "Lowpass";
	private final String highpass = "Highpass";
	private final String bandpass = "Bandpass";
	private final String stopband = "Stopband";
	private void createFilterType(FilterType type) {
		List<String> list = new ArrayList<String>();
		list.add(lowpass);
		list.add(highpass);
		list.add(bandpass);
		list.add(stopband);
		DspComboBox combo = new DspComboBox("Filter Type", list);
		if (type.equals(FilterType.Lowpass)) {
			combo.setSelected(lowpass);
		}
		else if (type.equals(FilterType.Highpass)) {
			combo.setSelected(highpass);
		}
		else if (type.equals(FilterType.Bandpass)) {
			combo.setSelected(bandpass);
		}
		else if (type.equals(FilterType.Stopband)) {
			combo.setSelected(stopband);
		}
		
		this.add(combo);
		
		combo.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				updateCutoffState(value);
				fireChange(value);
			}
		});
	}
	

	protected void updateCutoffState(String value) {
		if (value.equals(lowpass)) {
			cutoffLowWidget.setEnabled(true);
			cutoffHighWidget.setEnabled(false);
			
			setting.setFilterType(FilterType.Lowpass);
		}
		else if (value.equals(highpass)) {
			cutoffLowWidget.setEnabled(false);
			cutoffHighWidget.setEnabled(true);
			
			setting.setFilterType(FilterType.Highpass);
		}
		else if (value.equals(bandpass)){
			cutoffLowWidget.setEnabled(true);
			cutoffHighWidget.setEnabled(true);
			
			setting.setFilterType(FilterType.Bandpass);
		}
		else if (value.equals(stopband)) {
			cutoffLowWidget.setEnabled(true);
			cutoffHighWidget.setEnabled(true);
			
			setting.setFilterType(FilterType.Stopband);
		}

	}
	
	protected void updateAlgoState(String value) {
		if (value.equals(butterworth)) {
			setting.setFilterAlgo(FilterAlgo.Butterworth);
		}
		else if (value.equals(chebyshev1)) {
			setting.setFilterAlgo(FilterAlgo.Chebyshev1);
		}
		else if (value.equals(chebyshev2)) {
			setting.setFilterAlgo(FilterAlgo.Chebyshev2);
		}
		else if (value.equals(elliptic)) {
			setting.setFilterAlgo(FilterAlgo.Elliptic);
		}
		else if (value.equals(fir)) {
			setting.setFilterAlgo(FilterAlgo.Fir);
		}
	}
	
	private DspTextField createCutoff(CutoffType type, double value) {
		String title = null;
		if (type.equals(CutoffType.Low)) {
			title = "Cutoff [Low]";
		}
		else if (type.equals(CutoffType.High)) {
			title = "Cutoff [High]";
		}
		DspTextField text = new DspTextField(title);
		text.setValue(String.valueOf(value));
		this.add(text);
		return text;
	}
	
	private void createDelta(double delta) {
		DspTextField text = new DspTextField("Delta");
		text.setValue(String.valueOf(delta));
		this.add(text);
		text.addHandler(new DspWidgetHandler() {
			@Override
			public void onChange(String value) {
				setting.setDelta1(Double.valueOf(value));
				fireChange(value);
			}
		});	
	}
}
